#include "qerrormanager.h"
#include "qexppart.h"

QErrorManager* QErrorManager::m_instance = NULL;

QErrorManager::QErrorManager()
{
  #ifdef  LOG_ACTIVATED
  __TRACE__
  #endif
  #ifdef  LEAK_ACTIVATED
  __LEAK__
  #endif
}

QErrorManager::~QErrorManager()
{
  #ifdef  LOG_ACTIVATED
  __TRACE__
  #endif
  #ifdef  LEAK_ACTIVATED
  __LEAK__
  #endif
  reset(QStringList(),QStringList());
}


void QErrorManager::analyze(const QStringList& noPart,const QStringList& commonPart,const QStringList& pages,QEXPPart* part)
{
  #ifdef  LOG_ACTIVATED
  __TRACE__
  #endif
  #ifdef  LEAK_ACTIVATED
  __LEAK__
  #endif
  if(part && !pages.contains(part->get(EXP_ID).remove("\"")) && !noPart.contains(part->get(EXP_DESIGNATOR)))
  {
    part->clearError();

    if(part->get(EXP_CODE_PLP) == EXP_UNKNOWN)
      part->addError(getError(ERR_PLP_MISSING_ID));

    if(part->get(EXP_FOOTPRINT) == EXP_UNKNOWN)
      part->addError(getError(ERR_FOOTPRINT_MISSING_ID));

    if(part->get(EXP_REF_MANUFACTURER) == EXP_UNKNOWN&& !commonPart.contains(part->get(EXP_DESIGNATOR)))
      part->addError(getError(ERR_REF_MANU_MISSING_ID));

    if(part->get(EXP_MANUFACTURER) == EXP_UNKNOWN && !commonPart.contains(part->get(EXP_DESIGNATOR)))
      part->addError(getError(ERR_MANU_MISSING_ID));

	  
    QList<QEXPPart*> list = search(EXP_CODE_PLP,part->get(EXP_CODE_PLP));
    foreach(QEXPPart* other, list)
    {
      if(part->get(EXP_FOOTPRINT) != other->get(EXP_FOOTPRINT))
      {
        part->addError(getError(ERR_SAME_PLP_BUT_NOT_SAME_FOOTPRINT_ID));
        other->addError(getError(ERR_SAME_PLP_BUT_NOT_SAME_FOOTPRINT_ID));
      }

      if(part->get(EXP_REF_MANUFACTURER) != other->get(EXP_REF_MANUFACTURER)&& !commonPart.contains(part->get(EXP_DESIGNATOR)))
      {
        part->addError(getError(ERR_SAME_PLP_BUT_NOT_SAME_REF_ID));
        other->addError(getError(ERR_SAME_PLP_BUT_NOT_SAME_REF_ID));
      }
    }
    list.clear();

    list = search(EXP_REF_MANUFACTURER,part->get(EXP_REF_MANUFACTURER));
    foreach(QEXPPart* other, list)
    {
      if(part->get(EXP_FOOTPRINT) != other->get(EXP_FOOTPRINT))
      {
        part->addError(getError(ERR_SAME_REF_MANU_BUT_NOT_SAME_FOOTPRINT_ID));
        other->addError(getError(ERR_SAME_REF_MANU_BUT_NOT_SAME_FOOTPRINT_ID));
      }

      if(part->get(EXP_CODE_PLP) != other->get(EXP_CODE_PLP))
      {
        part->addError(getError(ERR_SAME_REF_MANU_BUT_NOT_SAME_PLP_ID));
        other->addError(getError(ERR_SAME_REF_MANU_BUT_NOT_SAME_PLP_ID));
      }
    }
    list.clear();

    list = search(EXP_VALUE,part->get(EXP_VALUE));
    foreach(QEXPPart* other, list)
    {
      if(part->get(EXP_FOOTPRINT) != other->get(EXP_FOOTPRINT))
      {
        part->addError(getError(ERR_SAME_VALUE_BUT_NOT_SAME_FOOTPRINT_ID));
        other->addError(getError(ERR_SAME_VALUE_BUT_NOT_SAME_FOOTPRINT_ID));
      }

      if(part->get(EXP_CODE_PLP) != other->get(EXP_CODE_PLP))
      {
        part->addError(getError(ERR_SAME_VALUE_BUT_NOT_SAME_PLP_ID));
        other->addError(getError(ERR_SAME_VALUE_BUT_NOT_SAME_PLP_ID));
      }
    }
    list.clear();

    if(part->get(EXP_CODE_PLP)!= EXP_UNKNOWN && !m_plp.contains(part->get(EXP_CODE_PLP)))
    {

      if(m_export.contains(part->get(EXP_CODE_PLP)))
        part->addError(getError(ERR_PLP_NOT_IN_BDD_BUT_EXPORT_ID));
      else
        part->addError(getError(ERR_PLP_NOT_IN_BDD_ID));
    }

	if(part->get(EXP_DESIGNATOR) == EXP_RESISTOR_DESIGNATOR || part->get(EXP_DESIGNATOR) == EXP_CAPACITOR_DESIGNATOR || part->get(EXP_DESIGNATOR) == EXP_SELF_DESIGNATOR )
	{
		if(!part->get(EXP_CODE_PLP).contains(part->get(EXP_REAL_VALUE)))
			part->addError(getError(ERR_NOT_SAME_VALUE_IN_PLP_AND_VALUE_ID));
	}
    m_parts << part;
  }
}

QErreur* QErrorManager::getError(QString id)
{
	#ifdef  LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef  LEAK_ACTIVATED
	__LEAK__
	#endif
	if(!m_errors.contains(id))
	{
		QErrorIniFile ini;
		ini.beginGroup(id);
		QString text = ini.value(ERR_TEXT).toString();
		quint32 importance =ini.value(ERR_IMPORTANCE).toInt();
		QColor color = ini.value(ERR_COLOR).value<QColor>();
		ini.endGroup();
		m_errors[id] = new QErreur(text,id,importance,color);
	}  
	return m_errors[id];
}

QErrorManager* QErrorManager::instance()
{
	#ifdef  LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef  LEAK_ACTIVATED
	__LEAK__
	#endif
	if(NULL == m_instance)
		m_instance = new QErrorManager();
	return m_instance;
}

void QErrorManager::destroy()
{
	#ifdef  LOG_ACTIVATED
	__TRACE__
	#endif 
	#ifdef  LEAK_ACTIVATED
	__LEAK__
	#endif
	if(m_instance)
	{
		delete m_instance; 
		m_instance = NULL;
	}
}


void QErrorManager::reset(QStringList plp,QStringList exportPlp)
{
	#ifdef  LOG_ACTIVATED
	__TRACE__
	#endif
	#ifdef  LEAK_ACTIVATED
	__LEAK__
	#endif
	m_plp = plp;
	m_export = exportPlp;
	QHash<QString,QErreur*>::iterator it;
	for(it = m_errors.begin();it!=m_errors.end();it++)
		delete it.value();
	m_errors.clear();
	m_parts.clear();
}


QList<QEXPPart*> QErrorManager::search(QString field,QString value)
{
  #ifdef  LOG_ACTIVATED
  __TRACE__
  #endif
  #ifdef  LEAK_ACTIVATED
  __LEAK__
  #endif
  QList<QEXPPart*> list;
  if(value != EXP_UNKNOWN && !value.isEmpty())
  {
    foreach( QEXPPart* part, m_parts)
    {
      if(part)
      {
        if(part->get(field) == value)
          list << part;
      }
    }
  }
  return list;
}